<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<style type="text/css">
			.map {
				width: 800px;
				height: 600px;
				background-color: #00FFFF;
				position: relative;
			}
		</style>
		<div class="map"></div>
		<script type="text/javascript">
			/**
			 * 地图：宽，高，背景颜色，小蛇和食物相对地图显示，随机位置显示，脱离文档流
			 */
			//函数写在自调用函数里面避免命名冲突
			//自调用		食物小方块
			(function() {
				var elements = []; //保存小方块
				//食物就是一个对象,有宽.高.颜色横纵坐标,先定义构造函数,然后创建对象
				function food(x, y, width, height, color) {
					this.x = x || 0;
					this.y = y || 0;
					this.width = width || 20;
					this.height = height || 20;
					this.color = color || "rgba(" + parseInt(Math.random() * 256) + "," + parseInt(Math.random() * 256) + "," + parseInt(Math.random() * 256) + ",1)";
				}
				//为原型链添加初始化方法,作用是在页面上显示该食物
				food.prototype.init = function(map) {
					remove();//先删除食物,外部无法访问
					var div = document.createElement("div");
					map.appendChild(div);
					div.style.width = this.width + "px";
					div.style.height = this.height + "px";
					div.style.backgroundColor = this.color;
					div.style.position = "absolute"; //脱离文档流
					//随机横纵坐标,放到这个div属性里边
					this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width;//地图宽度
					this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height;//地图高度
					div.style.left = this.x + "px";
					div.style.top = this.y + "px";

					elements.push(div);
				}
				//食物先保存在某一个地方,在这个地方找到这个食物,再找到这个食物的父级元素,从父级元素里边删掉
				function remove() {
					for (var i = 0; i < elements.length; i++) {
						var ele = elements[i];
						ele.parentNode.removeChild(ele);
						elements.splice(i, 1);//再次把elements中的子元素删除
					}
				}
				window.food = food; //外部使用,相当于全局
			}());

			//自调用		snake
			(function() {
				var elements = [];

				function snake(width, height, direction) {
					this.width = width || 20;
					this.height = height || 20;
					this.body = [{
							x: 3,
							y: 2,
							color: "red"
						},
						{
							x: 2,
							y: 2,
							color: "yellow"
						},
						{
							x: 1,
							y: 2,
							color: "yellow"
						}
					];//[]吃一个加一
					this.direction = direction || "right";
				};
				snake.prototype.init = function(map) {
					remove();//先删除之前的小蛇
					for (var i = 0; i < this.body.length; i++) {
						var obj = this.body[i];//数组中的每个元素都是一个对象
						var div = document.createElement("div");
						map.appendChild(div);
						div.style.position = "absolute"; //脱离文档流
						div.style.width = this.width + "px";
						div.style.height = this.height + "px";
						div.style.left = obj.x * this.width + "px";
						div.style.top = obj.y * this.height + "px";
						div.style.backgroundColor = obj.color;

						elements.push(div);
					}
				}
				snake.prototype.move = function(food, map) {
					var i = this.body.length - 1;//改变小蛇身体坐标位置
					for (; i > 0; i--) {
						this.body[i].x = this.body[i - 1].x;
						this.body[i].y = this.body[i - 1].y;
					}
					switch (this.direction) {//判断方向,改变小蛇头部坐标位置
						case "right":
							this.body[i].x += 1;
							break;
						case "left":
							this.body[i].x -= 1;
							break;
						case "top":
							this.body[i].y -= 1;
							break;
						case "bottom":
							this.body[i].y += 1;
							break;
					}
					//判断是否吃到食物
					//snake的头的坐标和食物的坐标一致
					var headX = this.body[0].x * this.width;
					var headY = this.body[0].y * this.height;
					if (headX == food.x && headY == food.y) {//判断snake的头的坐标和食物的坐标一致
						// alert("撞车");
						var last = this.body[this.body.length - 1];
						this.body.push({
							x: last.x,
							y: last.y,
							color: last.color
						})
						food.init(map);//把食物删掉,重新初始化食物
					}
				}

				function remove() {
					var i = elements.length - 1;
					for (; i >= 0; i--) {
						//先从当前的子元素中找到该子元素的父级元素,然后删除子元素
						var ele = elements[i];
						ele.parentNode.removeChild(ele);//从map地图上删除这个子元素
						elements.splice(i, 1);
					}
				}

				window.snake = snake;//snake暴露给window,外部访问
			}());

			//自调用 	游戏对象
			(function() {
				var that = null;

				function game(map) {
					this.food = new food();
					this.snake = new snake();
					this.map = map;
					that = this;//实例对象保存到变量里边
				}
				game.prototype.init = function() {
					this.food.init(this.map);
					this.snake.init(this.map);
					// setInterval(function(){
					// 	that.snake.move(that.food, that.map);
					// 	that.snake.init(that.map);
					// }, 200)
					this.runsnake(this.food, this.map);
					this.bindkey();
				}
				//小蛇奔跑吧
				game.prototype.runsnake = function(food, map) {
					var timer = setInterval(function() {
						this.snake.move(food, map);
						this.snake.init(map);
						var maxX = map.offsetWidth / this.snake.width;
						var maxY = map.offsetHeight / this.snake.height;
						var headX = this.snake.body[0].x;
						var headY = this.snake.body[0].y;
						if (headX < 0 || headX >= maxX) {
							clearInterval(timer);
							alert("game over");
						}
						if (headY < 0 || headY >= maxY) {
							clearInterval(timer);
							alert("game over");
						}
					}.bind(that), 120)
				}
				game.prototype.bindkey = function() {
					document.addEventListener("keydown", function(e) {
						// console.log(e.keyCode)
						//该this指向document,该this应该触发keydown事件的对象
						switch (e.keyCode) {
							case 37:
								this.snake.direction = "left";
								break;
							case 38:
								this.snake.direction = "top";
								break;
							case 39:
								this.snake.direction = "right";
								break;
							case 40:
								this.snake.direction = "bottom";
								break;
						}
					}.bind(that), false)
				}

				window.game = game;
			}());
			
			//初始化游戏对象
			var gm = new game(document.querySelector(".map"));
			gm.init();

			// var fd = new food();
			// fd.init(document.querySelector(".map"));
			// console.log(fd.x + "---" + fd.y)
			
			// var snake = new snake();
			// snake.init(document.querySelector(".map"));//先在地图上看到小蛇
			// 	snake.move(fd, document.querySelector(".map"));//走一步
			// snake.init(document.querySelector(".map"));//初始化重新画一条小蛇(先删除之前的小蛇，把现在的小蛇显示出来)
			// 	snake.move(fd, document.querySelector(".map"));
			
			// setInterval(function(){
			// 	snake.move(fd, document.querySelector(".map"));
			// 	snake.init(document.querySelector(".map"));
			// }, 200)
		</script>
	</body>
</html>
